package com.mtf.chatdemo.websocket;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mtf.chatdemo.common.Message;
import com.mtf.chatdemo.util.MessageUtil;
import com.mtf.chatdemo.util.WebSocketUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@Slf4j
@ServerEndpoint(value = "/chat/{userName}")
public class MyWebSocket {
    //Session代表与每个客户端的连接会话
    public Session session;

    //声明一个Set集合来存放每个客户端的WebSocket连接（也就是MyWebSocket对象）
//    private CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<>();

    //声明一个Map集合来存放键值对（“用户信息”，“Session会话”）:在线用户
    private static ConcurrentHashMap<String,MyWebSocket> userAboutSessionMap = new ConcurrentHashMap<>();

    //WebSocket连接被调用@PathParam("userName")
    //服务端给客户端发送消息
    @OnOpen
    public void OnOpenSuccess(@PathParam("userName") String userName, Session session){
        this.session = session;
        //将已经成功上线的用户信息存放到Map集合中
        userAboutSessionMap.put(userName,this);

        //某个用户成功上线，系统会给其他已经上线的用户发送一条“广播消息”
        //1、系统生成广播消息（视频返回的消息：JSON字符串）
        try {
            String message = MessageUtil.generateJSONMessage(true, userName, WebSocketUtil.getAllKeyFromMap(userAboutSessionMap), userName + "上线啦！");
            WebSocketUtil.sendBroadCastMessage(userAboutSessionMap,message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //服务端接收消息时被触发
    @OnMessage
    public void acceptMessage(String message,Session session){
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Message readValue = objectMapper.readValue(message, Message.class);
            String generateJSONMessage = MessageUtil.generateJSONMessage(false, readValue.getFromUserName(), readValue.getToUserName(), readValue.getMessage());
            WebSocketUtil.sendMessageOneToOne((String) readValue.getToUserName(),generateJSONMessage,userAboutSessionMap);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    //WebSocket连接断开时被调用
    @OnClose
    public void closeConnection(@PathParam("userName") String userName, Session session){
        userAboutSessionMap.remove(userName);

        //发送广播消息：XX用户已经下线！
        String generateJSONMessage = null;
        try {
            generateJSONMessage = MessageUtil.generateJSONMessage(true, userName, WebSocketUtil.getAllKeyFromMap(userAboutSessionMap), userName + "已经下线了");
            WebSocketUtil.sendBroadCastMessage(userAboutSessionMap,generateJSONMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //通过WebSocket连接客户端和服务端之间交换数据，在交换数据的过程中，
    //出现异常，比如不能发送某些格式数据，进而导致了连接的断开，而此时该方法被调用
    @OnError
    public void seeException(Throwable throwable){

    }
}
